package com.ycy.plugin;

import com.ycy.plugin.code.CodeAlgorithm;
import com.ycy.plugin.config.Config;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.spec.AlgorithmParameterSpec;

/**
 * DES对称加密
 */
public class DESAlgorithm extends SymmetricAlgorithm {

  public DESAlgorithm(String secretType, String dataSecret) {
    this.secretType = secretType;
    this.dataSecret = dataSecret;
    this.dataSecretiv = dataSecret;
  }

  public DESAlgorithm(String secretType, String dataSecret, String dataSecretiv, String out, String toCase) {
    this.secretType = secretType;
    this.dataSecret = dataSecret;
    this.dataSecretiv = dataSecretiv;
    this.out = out;
    this.toCase = toCase;
  }

  /**
   * 加密
   *
   * @param data 加密数据
   * @return 加密后的数据
   */
  public String encrypt(String data) throws Exception {
    byte[] DESkey = this.dataSecret.getBytes(StandardCharsets.UTF_8);
    byte[] DESIV = this.dataSecretiv.getBytes(StandardCharsets.UTF_8);
    DESKeySpec keySpec = new DESKeySpec(DESkey);
    AlgorithmParameterSpec iv = new IvParameterSpec(DESIV, 0, 8);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey key = keyFactory.generateSecret(keySpec);// 得到密钥对象
    Cipher enCipher = Cipher.getInstance(this.secretType);
    enCipher.init(Cipher.ENCRYPT_MODE, key, iv);
    byte[] encryptByte = enCipher.doFinal(data.getBytes(StandardCharsets.UTF_8));

    String encryptStr = Config.hex.equalsIgnoreCase(this.out) ? CodeAlgorithm.HexEncode(encryptByte) : CodeAlgorithm.Base64Encode(encryptByte);

    if (Config.touppercase.equalsIgnoreCase(this.toCase)) {
      return encryptStr.toUpperCase();
    }
    if (Config.tolowercase.equalsIgnoreCase(this.toCase)) {
      return encryptStr.toLowerCase();
    }
    return encryptStr;
  }

  /**
   * 解密
   *
   * @param data 解密数据
   * @return 解密后的数据
   * @throws Exception
   */
  public String decrypt(String data) throws Exception {
    byte[] DESkey = dataSecret.getBytes(StandardCharsets.UTF_8);
    byte[] DESIV = dataSecretiv.getBytes(StandardCharsets.UTF_8);
    DESKeySpec keySpec = new DESKeySpec(DESkey);
    AlgorithmParameterSpec iv = new IvParameterSpec(DESIV, 0, 8);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey key = keyFactory.generateSecret(keySpec);
    Cipher deCipher = Cipher.getInstance(this.secretType);
    deCipher.init(Cipher.DECRYPT_MODE, key, iv);
    byte[] decodeByte = Config.hex.equalsIgnoreCase(this.out) ? CodeAlgorithm.HexDecode(data) : CodeAlgorithm.Base64Decode(data);
    byte[] pasByte = deCipher.doFinal(decodeByte);
    return new String(pasByte, StandardCharsets.UTF_8);
  }

  public static void main(String[] args) {

    //我方发送给openApi的请求参数
    String a = "{\"test\":\"testRequest\"}";
    //拼接openApi请求第三方的请求报文（第三方请求openApi也是这种格式）
    String dataSecret = "1234567890abcdef";

    DESAlgorithm desAlgorithm = new DESAlgorithm("DES/CBC/PKCS5Padding", dataSecret);
    try {
      String encrypt = desAlgorithm.encrypt(a);
      System.out.println(encrypt);

      String decrypt = desAlgorithm.decrypt(encrypt);
      System.out.println(decrypt);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }


}
